/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package utilidades;

import java.sql.*;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * Clase que representa y facilita la interaccion con una BD, provee todos lo
 * metodos necesarios para ello.
 *
 * @author felipe
 */
public class GestorBD {

    private Connection conexion;
    private Statement statement;
    private ResultSet resultSet;
    private ResultSetMetaData resultSetMD;
    private String driver;
    private String location;
    private String user;
    private String pass;

    /**
     * Constructor de la clase Conection en el que el usuario introduce los
     * datos de la conexión.
     */
    public GestorBD() {
        this.driver = "org.apache.derby.jdbc.ClientDriver";
        this.location = "jdbc:derby://localhost:1527/FinancesDB";//
        this.user = "felipe";
        this.pass = "felipe";
    }

    /**
     * Registra Driver y abre la conexion.
     */
    public void abrir() {
        this.driverConection();
        this.openConnection();
    }

    /**
     * Cierra Statement, ResultSet y Conexion.
     */
    public void cerrar() {
        this.closeStatement();
        this.closeResultSet();
        this.closeConection();
    }

    /**
     * Registra el driver necesario para gestionar conexión.
     */
    private void driverConection() {
        try {
            Class.forName(this.driver);
        } catch (ClassNotFoundException ex) {
            Logger.getLogger(GestorBD.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    /**
     * Utiliza la información necesaria para abrir una conexion.
     */
    private void openConnection() {
        try {
            this.setConecion(DriverManager.getConnection(this.location, this.user, this.pass));
        } catch (SQLException ex) {
            Logger.getLogger(GestorBD.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    /**
     * Obtiene el Result Set generado por un Statement sobre una conexión
     * abierta.
     *
     * @param query Cconsulta SQL.
     */
    public void obtainResultSet(String query) {
        try {
            this.setStatement((this.getConexion()).createStatement());
            this.setResultSet(this.getStatement().executeQuery(query));
        } catch (SQLException ex) {
            Logger.getLogger(GestorBD.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    /**
     * Obtiene el Result Set generado por un Statement sobre una conexión
     * abierta.
     *
     * @param query Cconsulta SQL.
     */
    public void insertarYBorrarLinea_s(String query) {
        try {
            this.setStatement((this.getConexion()).createStatement());
            this.getStatement().executeUpdate(query);
        } catch (SQLException ex) {
            Logger.getLogger(GestorBD.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    /**
     * Dado una query devuelve un arrayList con los resultados de la misma.
     *
     * @param query
     * @return
     */
    public ArrayList<String> obtenerResultadoDelSelectFechaEnArray(String query) {
        ArrayList<String> resultados = new ArrayList<>();
        try {
            obtainResultSet(query);
            setResultSetMD(getResultSet().getMetaData());
            int nColumn = getResultSetMD().getColumnCount();
            while (getResultSet().next()) {
                for (int i = 1; i <= nColumn; i++) {
                    resultados.add(getResultSet().getString(i));
                }
            }
        } catch (SQLException ex) {
            Logger.getLogger(GestorBD.class.getName()).log(Level.SEVERE, null, ex);
        }
        return resultados;
    }

    /**
     * Dado una query devuelve un arrayList con los resultados de la misma.
     *
     * @param query
     * @return
     */
    public ArrayList<Float> obtenerResultadoDelSelectCierreEnArray(String query) {
        ArrayList<Float> resultados = new ArrayList<>();
        try {
            obtainResultSet(query);
            setResultSetMD(getResultSet().getMetaData());
            int nColumn = getResultSetMD().getColumnCount();
            while (getResultSet().next()) {
                for (int i = 1; i <= nColumn; i++) {
                    resultados.add(getResultSet().getFloat(i));
                }
            }
        } catch (SQLException ex) {
            Logger.getLogger(GestorBD.class.getName()).log(Level.SEVERE, null, ex);
        }
        return resultados;
    }

    /**
     * Cierra un ResultSet.
     */
    private void closeResultSet() {
        try {
            if (this.getResultSet() != null) {
                this.getResultSet().close();
            }
        } catch (SQLException ex) {
            Logger.getLogger(GestorBD.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    /**
     * Cierra un Statement.
     */
    private void closeStatement() {
        try {
            if (this.getStatement() != null) {
                this.getStatement().close();
            }
        } catch (SQLException ex) {
            Logger.getLogger(GestorBD.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    /**
     * Cierra una conexión abierta.
     */
    private void closeConection() {
        try {
            if (this.getConexion() != null) {
                this.getConexion().close();
            }
        } catch (SQLException ex) {
            Logger.getLogger(GestorBD.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    /**
     * @return bdConection
     */
    public Connection getConexion() {
        return conexion;
    }

    /**
     * @param bdConection
     */
    public void setConecion(Connection connection) {
        this.conexion = connection;
    }

    /**
     * @return statement
     */
    public Statement getStatement() {
        return statement;
    }

    /**
     * @param statement
     */
    public void setStatement(Statement statement) {
        this.statement = statement;
    }

    /**
     * @return resultSet
     */
    public ResultSet getResultSet() {
        return resultSet;
    }

    /**
     * @param resultSet
     */
    public void setResultSet(ResultSet resultSet) {
        this.resultSet = resultSet;
    }

    /**
     * @return resultSetMD
     */
    public ResultSetMetaData getResultSetMD() {
        return resultSetMD;
    }

    /**
     * @param resultSetMD
     */
    public void setResultSetMD(ResultSetMetaData resultSetMD) {
        this.resultSetMD = resultSetMD;
    }
}